
#include "ChessController.h"

ChessController::ChessController()
{
	selectedPiece = NULL;
}

ChessController::ChessController(ChessGame* game, char * playMode)
{	selectedPiece = NULL;
	this->gameMode = playMode;
	this->game = game;
	this->game->SetGameMode(gameMode);
	status = "start";
	inTimer = false;
	currentFile = "";
}

ChessController::~ChessController()
{
	delete(this->game);
	//delete(this->view);
}


void ChessController::on_CellSelected(int row, int col, int button)
{
	if(!game->currentPlayerIsHuman())
		return;
	// update currentCell
	currentCell = game->GetCell( row,col );
	
	// if a piece hasn't been selected
	if (selectedPiece == NULL) {
		// (nothing should be highlighted)
		
		// if we hit an empty cell
		if (currentCell->GetPiece() == NULL) {
			// keep it null
		} else if (currentCell->GetPiece()->GetColor() == game->GetCurrentPlayersColor()) {// if we hit a piece of our own color
			// set selectedPiece to currentCell's piece
			selectedPiece = currentCell->GetPiece();
		}else {
			// Nothing
		}

	} else if (currentCell == selectedPiece->GetCell()) { // if we hit the already selected cell
		selectedPiece = NULL;
	} else {
		
		// a cell has been selected and we hit something other than
		// the cell of our selectedPiece
		// if the current cell is a valid move for the selected piece
		if (game->IsValidMove(selectedPiece, currentCell)) {
			// move selectedPiece to currentCell
			game->Move(selectedPiece, currentCell);

			if (game->PlayerInCheck(game->GetCurrentPlayersColor())) {
				if (game->GetCurrentPlayersColor() == WHITE) {
					//status="check";
					view->SetStatusBar("White in check!");
				}
				else {
					//status="check";
					view->SetStatusBar("Black in check!");
				}
				
				// check to see if current player is in check mate
				if (game->PlayerInCheckMate(game->GetCurrentPlayersColor())) {
					view->SetStatusBar("Check Mate!");
					status = "checkmate";
				}
			} else {
				view->SetStatusBar("");
			}
			
			// clear selectedPiece
			selectedPiece = NULL;
		}
		// otherwise the currentCell is an invalid move
		else {
			// if we hit an empty cell
			if (currentCell->GetPiece() == NULL) {
				
				// clear selectedPiece
				selectedPiece = NULL;
			}
			// if we hit a piece of our own color
			else if (currentCell->GetPiece()->GetColor() == game->GetCurrentPlayersColor()) {
				
				// set selectedPiece to currentCell's piece
				selectedPiece = currentCell->GetPiece();
				
			}
			// if we hit the other player's piece
			else {
				
				// clear selectedPiece
				selectedPiece = NULL;
				
			}
			
		}
		
	}

	// update view
	UpdateView();

	
}


void ChessController::on_DragStart(int row,int col)
{
}


bool ChessController::on_DragEnd(int row,int col)
{	
	return false;
}


void ChessController::on_NewGame()
{
	while(inTimer == true);
	delete(game);
	selectedPiece = NULL;
	currentCell = NULL;
	status = "start";
	this->game = new ChessGame();
	this->game->SetGameMode(gameMode);
	UpdateView();
}


void ChessController::on_SaveGame()
{
	if(currentFile != ""){
		game->saveToXml(currentFile);
	} else {
		on_SaveGameAs();
	}
	
}


void ChessController::on_SaveGameAs()
{
	currentFile = view->SelectSaveFile();
	if(currentFile != "")
		game->saveToXml(currentFile);
}


void ChessController::on_LoadGame()
{
	string fileLoc = view->SelectLoadFile();

	if(fileLoc== "")
		return;

	delete(game);
	selectedPiece = NULL;
	currentCell = NULL;
	status = "start";

	this->game = new ChessGame(fileLoc.c_str());
	this->game->SetGameMode(gameMode);
	UpdateView();
}


void ChessController::on_UndoMove()
{
	while(inTimer == true);
	selectedPiece = NULL;
	game->UndoMove(game->PopMostRecentMoveRecord());
	status = "start";
	UpdateView();
}


void ChessController::on_QuitGame()
{

}

	
void ChessController::on_TimerEvent()
{
	inTimer = true;
	if(game->currentPlayerIsHuman()){
		inTimer = false;
		return;
	}
	if (game->PlayerInCheck(game->GetCurrentPlayersColor())) {
		if (game->GetCurrentPlayersColor() == WHITE) {
			//status="check";
			view->SetStatusBar("White in check!");
		}
		else {
			//status="check";
			view->SetStatusBar("Black in check!");
		}
				
		// check to see if current player is in check mate
		if (game->PlayerInCheckMate(game->GetCurrentPlayersColor())) {
			view->SetStatusBar("Check Mate!");
			status = "checkmate";
		}
	}




	if(status=="start"){
		// run through each cell
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				Piece * temppiece = this->game->GetCell(i,j)->GetPiece();
				if(temppiece != NULL && game->GetCurrentPlayersColor()==temppiece->GetColor()){
					if(game->GetValidMoves(temppiece)->size() > 0){
						// set selectedPiece to currentCell's piece

						currentCell = game->GetCell(i,j);
						selectedPiece = currentCell->GetPiece();

						std::set<Cell*>* validMoves = game->GetValidMoves(selectedPiece);
						set<Cell*>::iterator it(validMoves->begin());
						Cell* tempCell;
						while( it != validMoves->end()){
							tempCell = *it;
							if(tempCell->GetPiece() != NULL){
								status = "selected";
								break;
							}
							++it;
						}
						if(status == "selected")
							break;
						else
							status = "possibleselected";
						
						
					}
				}
			}
			if(status == "selected")
				break;
		}
	} else if(status == "selected" || status == "possibleselected"){
		std::set<Cell*>* validMoves = game->GetValidMoves(selectedPiece);
		set<Cell*>::iterator it(validMoves->begin());

		while( it != validMoves->end()){
			currentCell = *it;
			if(currentCell->GetPiece() != NULL)
				break;
			++it;
		}
		game->Move(selectedPiece, currentCell);
		status = "start";
		// clear selectedPiece
		selectedPiece = NULL;
	}else if(status == "checkmate"){

	}
	UpdateView();
	inTimer = false;
}


void ChessController::SetView(IChessView* view)
{
	this->view = view;
}

void ChessController::HighlightValidMoves(Piece* piece)
{
	std::set<Cell*>* tmp = game->GetValidMoves(piece);
	std::set<Cell*>::iterator it = tmp->begin();
	
	while (it != tmp->end()) {
		view->HighlightSquare( (*it)->GetRow(),(*it)->GetCol(), GREEN_SQUARE);
		it++;
	}
	
}



void ChessController::UpdateView()
{	
	// run through each cell
	for (int i = 0; i < 8; i++) {
		for (int j = 0; j < 8; j++) {
			// clear highlighted squares
			view->UnHighlightSquare( i,j );
		
			// place pieces where they should be
			if (game->GetPiece( i,j ) == NULL) {
				view->ClearPiece( i,j );
			} else {
				view->PlacePiece( i,j, game->GetPiece( i,j )->GetImageName());
			}
		}
	}
	bool possibleMoveExists = false;
	// run through each cell
	for (int i = 0; i < 8; i++) {
		for (int j = 0; j < 8; j++) {
			Piece * temppiece = this->game->GetCell(i,j)->GetPiece();
			if(temppiece != NULL && game->GetCurrentPlayersColor()==temppiece->GetColor()){
				if(game->GetValidMoves(temppiece)->size() > 0){
					// set selectedPiece to currentCell's piece
					possibleMoveExists = true;			
					break;
				}
				if(possibleMoveExists == true)
					break;
			}
		}
	}
	if(!possibleMoveExists)
		view->SetStatusBar("Stalemate!");
	// highlight selected piece & its valid moves
	if (selectedPiece != NULL) {
		view->HighlightSquare( selectedPiece->GetRow(),selectedPiece->GetCol(), BLUE_SQUARE);
		HighlightValidMoves(selectedPiece);
	}

	if(game->GetCurrentPlayersColor() == WHITE){
		view->SetBottomLabel("Whites turns");
		view->SetTopLabel("");
	} else {
		view->SetBottomLabel("");
		view->SetTopLabel("Blacks turns");
	}
	if (game->PlayerInCheck(game->GetCurrentPlayersColor())) {
		if (game->GetCurrentPlayersColor() == WHITE) {
			//status="check";
			view->SetStatusBar("White in check!");
		}
		else {
			//status="check";
			view->SetStatusBar("Black in check!");
		}
				
		// check to see if current player is in check mate
		if (game->PlayerInCheckMate(game->GetCurrentPlayersColor())) {
			view->SetStatusBar("Check Mate!");
			status = "checkmate";
		}
	} else if(possibleMoveExists)
		view->SetStatusBar("");

	
}

